/*
* fOSC = 6.249.472 Hz
*/

#include <pic18fregs.h>
#include <pic16/pic18f96j60.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>

#include "HardwareProfile.h"
#include "LCDBlocking.h"

#include "lcd.h"

#define SECONDSADAY 24*60*60

unsigned char _MALLOC_SPEC heap[256];

volatile Time* current;

void init();
void initTime(Time* time, Time* alarm);

/*

//This would be the interrupt routine when using timer0 interrupts.
void timer0_ISR(void) __interrupt (1)
{
	static unsigned int i = 0;
	static int alternate = 0;
	unsigned int tmp;

	INTCONbits.T0IF = 0;

	i++;

	if((alternate == 0 && i > 31250) || (alternate == 1 && i > 31250))
	{
		++seconds;

		tmp = seconds;

		time->hours = tmp / 3600;
		tmp %= 3600;
		time->minutes = tmp / 60;
		tmp %= 60;
		time->seconds = tmp;

		alternate = (alternate==1)?0:1;

		i = 0;
	}
}
*/

//This is the interrupt routine for timer0 interrupt.
void RTC_ISR(void) __interrupt (1)
{
	//Preload for 1 second interrupt interval
	TMR1H |= 0x80;

	//Clear overflow flag
	PIR1bits.TMR1IF = 0;

	current->totalSeconds++;
	current->totalSeconds %= (unsigned long)SECONDSADAY;
	updateTime(current);
}

void main()
{
	int i;
	Time* alarm = (Time*)malloc(sizeof(Time));
	current = (Time*)malloc(sizeof(Time));

	init();

	initTime(current, alarm);

	setTime(current, CURRENT_TIME_OFFSET);

	setTime(alarm, ALARM_TIME_OFFSET);

	//Preload for 1 second interrupt interval
	TMR1H = 0x80;
	TMR1L = 0x00;

	//Enable all interrupts
	INTCONbits.GIE = 1;

	while(1)
	{
		while(current->totalSeconds != alarm->totalSeconds)
		{
			showTime(current, CURRENT_TIME_OFFSET);

			waitMs(250);
		}

		i = 0;

		while(i < 60)
		{
			LATJbits.LATJ0 ^= 1;
			showTime(current, CURRENT_TIME_OFFSET);
			i++;

			waitMs(500);
		}
	}
}

void init()
{
	//Configure LED
	TRISJbits.TRISJ0 = 0;
	LATJbits.LATJ0 = 0;

	TRISGbits.TRISG5 = 0;

	//Initialize LCD
	LCDInit();

	//Configure Timer0
/*	T0CONbits.T08BIT = 1;
	T0CONbits.T0CS = 0;
	T0CONbits.PSA = 1;
	T0CONbits.TMR0ON = 1;
*/
	//Configure interrupts
/*	INTCONbits.T0IE = 1;
	INTCON2bits.T0IP = 1;
	INTCONbits.T0IF = 0;
*/
	//Preload for 1 second interrupt interval
	TMR1H = 0x80;
	TMR1L = 0x00;

	T1CONbits.RD16 = 0;
	T1CONbits.T1RUN = 0;
	T1CONbits.T1CKPS1 = 0;
	T1CONbits.T1CKPS0 = 0;
	T1CONbits.TMR1CS = 1;
	T1CONbits.T1OSCEN = 1;
	T1CONbits.T1SYNC = 1;

	T1CONbits.TMR1ON = 1;

	PIE1bits.TMR1IE = 1;
	IPR1bits.TMR1IP = 1;
	PIR1bits.TMR1IF = 0;

	INTCONbits.PEIE = 1;

	//Configure buttons
	BUTTON0_TRIS = 1;
	BUTTON1_TRIS = 1;
}

void initTime(Time* time, Time* alarm)
{
	int i;

	//Initialize time
	time->hours = 0;
	time->minutes = 0;
	time->seconds = 0;
	time->totalSeconds = 0;

	//Initialize alarm
	alarm->hours = 0;
	alarm->minutes = 0;
	alarm->seconds = 0;
	alarm->totalSeconds = 0;

	for(i = 0; i < LCDChars; i++)
		LCDText[i] = 0;

	LCDUpdate();

	backlightOn();

	showTime(time, CURRENT_TIME_OFFSET);
	showTime(alarm, ALARM_TIME_OFFSET);
}

